CS-10616: Reimplement boxel workspace pull command#4355
Conversation
Port pull command and shared libraries from standalone boxel-cli. Adds MatrixClient, RealmAuthClient, RealmSyncBase, and CheckpointManager shared libs. Registers pull under `boxel workspace pull` subcommand. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
now that we have real realm integration don't forget to add tests for this against a running realm |
…eding - Update noopPrerenderer to return a valid RenderResponse with error field so the indexer handles it gracefully instead of crashing on undefined - Seed test realm files via fileSystem parameter (matching realm-server test pattern) instead of HTTP POST via seedRealmFile - Add missing test cases: preserves local-only files, recursive subdirs - Remove unused seedRealmFile helper and mock test infrastructure Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
a0bf836 to
d20a12f
Compare
Host Test Results0 tests 0 ✅ 0s ⏱️ Results for commit d20a12f. |
Preview deployments |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7cf154049c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
0f3051f to
b407dcf
Compare
…only checkpoints - Split authedFetch into authedRealmFetch and authedRealmServerFetch for clarity - Fix P1: handle expired server token during realm-auth prefetch gracefully so the 401 retry path still works - Fix P2: persist checkpoint after delete-only pulls (not just downloads) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
b407dcf to
6d437cb
Compare
| for (const [relativePath] of remoteFiles) { | ||
| try { | ||
| const localPath = path.join(this.options.localDir, relativePath); | ||
| await this.downloadFile(relativePath, localPath); | ||
| downloadedFiles.push(relativePath); | ||
| } catch (error) { | ||
| this.hasError = true; | ||
| console.error(`Error downloading ${relativePath}:`, error); | ||
| } |
There was a problem hiding this comment.
this is downloading files seriallly? why? we should be downloading files concurrently
| for (const relativePath of filesToDelete) { | ||
| try { | ||
| const localPath = localFiles.get(relativePath); | ||
| if (localPath) { | ||
| await this.deleteLocalFile(localPath); | ||
| deletedFiles.push(relativePath); | ||
| console.log(` Deleted: ${relativePath}`); | ||
| } | ||
| } catch (error) { |
There was a problem hiding this comment.
why are we doing these batch operations serially? we should be using atomic operations for this
| const checkpointManager = new CheckpointManager(this.options.localDir); | ||
| const deleteChanges: CheckpointChange[] = Array.from(filesToDelete).map( | ||
| (f) => ({ | ||
| file: f, | ||
| status: 'deleted' as const, | ||
| }), | ||
| ); | ||
| const preDeleteCheckpoint = checkpointManager.createCheckpoint( | ||
| 'remote', | ||
| deleteChanges, | ||
| `Pre-delete checkpoint: ${filesToDelete.size} files not on server`, | ||
| ); | ||
| if (preDeleteCheckpoint) { | ||
| console.log( | ||
| `\nCheckpoint created before deletion: ${preDeleteCheckpoint.shortHash}`, | ||
| ); |
There was a problem hiding this comment.
where are the tests for the checkpoint stuff here?
|
so per our discussion with @lukemelia yes, we are copying this over and making targetted adjustments as we see them. sorry for the confusion! |

Summary
boxel workspace pullcommand from standalone boxel-cli into monorepoboxel realm pullsubcommandTest plan
pnpm --filter @cardstack/boxel-cli test— 31 tests passpnpm --filter @cardstack/boxel-cli build— builds successfullypnpm --filter @cardstack/boxel-cli lint— no errors🤖 Generated with Claude Code